import { Cartesian3, createGuid, Entity, Viewer } from "cesium";
import type { BaseEntityOptions } from "../interfaces/entity";
import type { EntityManager } from "./EntityManager";
import { Transforms } from "cesium";
import { HeadingPitchRoll } from "cesium";

/**
 * Cesium 实体基类
 * 封装通用属性和方法
 */
export abstract class BaseEntity {
  /** Cesium Viewer 实例 */
  private _viewer: Viewer | undefined = undefined;
  protected _entity: Entity;
  private static _idCounter = 0;
  private _EntityManager: EntityManager | undefined = undefined;
  private _components: Map<
    keyof BaseEntityOptions,
    BaseEntityOptions[keyof BaseEntityOptions]
  > = new Map();

  constructor(options: BaseEntityOptions) {
    const {
      Base: { id, name, description, show = true } = {
        id: createGuid(),
        name: "",
        description: "",
        show: true,
      },
      Position: { lat, alt, lon } = {
        lon: 122,
        lat: 28,
        alt: 0,
      },
    } = options;
    this._components.set("Base", { id, name, description, show });
    this._components.set("Position", { lat, alt, lon });

    const position = Cartesian3.fromDegrees(lon, lat, alt);
    this._entity = new Entity({
      id: id || `entity_${BaseEntity._idCounter++}`,
      name,
      description,
      show,
      position,
      orientation: Transforms.headingPitchRollQuaternion(
        position,
        new HeadingPitchRoll(0, 0, 0)
      ),
      // 其他通用属性...
    });
    // 更新存储的组件数据
    this.updateComData(options);
  }

  // 获取Cesium原生实体（供外部调用）
  get entity(): Entity {
    return this._entity;
  }
  // 获取装备
  get entityManager(): EntityManager | undefined {
    return this._EntityManager;
  }
  // 装备更新
  set entityManager(value: EntityManager) {
    this._EntityManager = value;
  }
  // 获取viewer
  get viewer(): Viewer | undefined {
    return this._viewer;
  }
  // 装备viewer
  set viewer(value: Viewer) {
    this._viewer = value;
  }

  // 通用方法 - 显示/隐藏
  setVisible(visible: boolean): void {
    this._entity.show = visible;
  }

  // 抽象方法 - 子类必须实现特有外观
  protected abstract setAppearance(): void;

  private updateComData(options: BaseEntityOptions) {
    for (const key in options)
      this._components.set(
        key as keyof BaseEntityOptions,
        options[key as keyof typeof options]
      );
  }
}
